Add instructions for testing ostree-boot
authorSimon McVittie <smcv@debian.org>
Fri, 23 Aug 2019 09:48:09 +0000 (10:48 +0100)
committerSimon McVittie <smcv@debian.org>
Tue, 27 Aug 2019 19:24:57 +0000 (20:24 +0100)
Co-authored-by: Felix Krull <f_krull@gmx.de>
debian/ostree-boot-examples/README.md [new file with mode: 0644]
debian/ostree-boot-examples/deb-ostree-builder [new file with mode: 0644]
debian/ostree-boot-examples/modified-deb-ostree-builder [new file with mode: 0644]
debian/ostree-boot-examples/ostree-1.conf [new file with mode: 0644]
debian/ostree-boot-examples/ostree-2.conf [new file with mode: 0644]

diff --git a/debian/ostree-boot-examples/README.md b/debian/ostree-boot-examples/README.md
new file mode 100644 (file)
index 0000000..bf08b72
--- /dev/null
@@ -0,0 +1,93 @@
+# Testing ostree-boot on an existing system
+
+Start from an amd64 Debian system (9 or newer, as long as a backported
+ostree-boot package is available) - it will be switched to a Debian
+unstable (sid) OSTree-based installation as part of following these
+instructions. A VM is obviously most convenient, but bare metal should
+work equally.
+
+The installation needs to satisfy the following requirements:
+
+* It must have a separate /boot partition (this is a general libostree
+  limitation [1]).
+* The root partition must not be encrypted.
+* It must use GRUB and BIOS booting. Other bootloaders or EFI may require
+  different bootloader setup steps. [2]
+
+[1]: https://github.com/ostreedev/ostree/issues/1452
+[2]: https://pagure.io/workstation-ostree-config/blob/5b574d39c63b82b397df789eb4a75a5bdcc13dd0/f/README-install-inside.md
+
+We need the bootloader integration files on the non-OSTree system from
+which we are switching, as well as in the OSTree-based installation,
+so the bootloader gets configured properly when we "ostree admin deploy":
+
+    # apt-get update
+    # apt-get install ostree ostree-boot multistrap
+
+Create the ostree system repository and a stateroot:
+
+    # ostree admin init-fs /
+    # ostree admin os-init debian
+
+Copy modified-deb-ostree-builder, ostree-1.conf and ostree-2.conf from
+debian/ostree-boot-examples/ to the test machine, and run the builder
+script:
+
+    # chmod +x ./deb-ostree-builder
+    # ./deb-ostree-builder ./ostree-1.conf sid-1 /ostree/repo
+    # ./deb-ostree-builder ./ostree-2.conf sid-2 /ostree/repo
+
+If ostree-boot is not available in the target suite in the Debian
+archive yet, then you will need to edit ostree-1.conf and ostree-2.conf to
+remove ostree-boot from the bootstrap, and instead put the ostree-boot,
+ostree and libostree-1-1 packages in /root/extra-packages, and use
+modified-deb-ostree-builder instead of deb-ostree-builder. This is a
+temporary hack to solve the chicken-and-egg situation of not adding
+ostree-boot to the Debian archive until it is testable, but not being
+able to test it until it is in the archive.
+
+Then we deploy the first of those commits:
+
+    # ostree admin deploy --karg-proc-cmdline --os=debian os/debian/amd64/sid-1
+    # deploy=$(find /ostree/deploy/debian/deploy/* -maxdepth 0 -type d)
+
+Next, we set the root password and copy a few essential configuration files
+into the initial deployment:
+
+    # chroot $deploy passwd root
+    # : > $deploy/etc/machine-id
+    # for f in etc/fstab etc/default/grub; do cp /$f $deploy/$f; done
+
+Finally, we set up the bootloader by pointing GRUB at the configuration file
+managed by ostree. Alternatively, you can run update-grub by hand after every
+new ostree deployment. This step may be different or unnecessary for other
+bootloaders.
+
+    # mv /boot/grub/grub.cfg /boot/grub/grub.cfg.backup
+    # ln -s ../loader/grub.cfg /boot/grub/grub.cfg
+
+Now reboot. Make sure to select the new ostree entry in the bootloader. Log in
+as root using the password you selected before. The system is rather
+unconfigured (network access can be set up in /etc/network/interfaces). This is
+the commit built from the ostree-1.conf file, so it doesn't have the hello
+package:
+
+    # hello
+    -bash: hello: command not found
+
+Now we can deploy the second commit from inside the ostree system:
+
+    # ostree admin deploy --karg-proc-cmdline --os=debian os/debian/amd64/sid-2
+
+Reboot again. Note that your new deployment will again be the first ostree
+entry in the menu, labelled `ostree:0`. Your old deployment has been moved
+down the menu to `ostree:1`. The root password and the other configuration
+was copied from the first deployment, so you can log in as before.
+
+Now try running the hello command again:
+
+    # hello
+    Hello, world!
+
+This shows we've now booted the second commit built from ostree-2.conf, which
+includes the hello package.
diff --git a/debian/ostree-boot-examples/deb-ostree-builder b/debian/ostree-boot-examples/deb-ostree-builder
new file mode 100644 (file)
index 0000000..7dc9d2d
--- /dev/null
@@ -0,0 +1,309 @@
+#!/bin/bash -e
+
+# deb-ostree-builder - Build bootable Debian OSTree commits
+#
+# Copyright (C) 2017  Dan Nicholson <nicholson@endlessm.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+PROG=$(readlink -f "$0")
+PROGDIR=$(dirname "$PROG")
+
+# Defaults
+ARCH=$(dpkg --print-architecture)
+BUILDDIR=
+GPG_SIGN=()
+GPG_HOMEDIR=
+
+usage() {
+    cat <<EOF
+Usage: $0 [OPTION...] CONFIG SUITE REPO
+
+  -a, --arch           build architecture
+  -d, --dir            build directory
+  --gpg-sign           GPG key ID to use for signing
+  --gpg-homedir                GPG homedir to find keys
+  -h, --help           show this message and exit
+
+deb-ostree-builder constructs a Debian OS for use as a bootable
+OSTree. It uses debootstrap to construct the OS, adjusts it to be
+compatible with OSTree, and then commits it to a repository.
+
+CONFIG is a multistrap configuration file. SUITE is the distribution
+codename. This is used for the OSTree ref and must match the
+multistrap configuration. REPO is the path the the OSTree repository
+where the commit will be made.
+EOF
+}
+
+ARGS=$(getopt -n "$0" \
+             -o a:d:h \
+             -l arch:,dir:,gpg-sign:,gpg-homedir:,help \
+             -- "$@")
+eval set -- "$ARGS"
+
+while true; do
+    case "$1" in
+       -a|--arch)
+           ARCH=$2
+           shift 2
+           ;;
+        -d|--dir)
+            BUILDDIR=$2
+            shift 2
+            ;;
+       --gpg-sign)
+           GPG_SIGN+=($2)
+           shift 2
+           ;;
+       --gpg-homedir)
+           GPG_HOMEDIR=$2
+           shift 2
+           ;;
+       -h|--help)
+           usage
+           exit 0
+           ;;
+       --)
+           shift
+           break
+           ;;
+    esac
+done
+
+if [ $# -lt 3 ]; then
+    echo "Must specify CONFIG, SUITE and REPO" >&2
+    exit 1
+fi
+
+CONFIG=$1
+SUITE=$2
+REPO=$3
+
+# Mount cleanup handler
+DEVICES_MOUNTED=false
+cleanup_mounts()
+{
+    if $DEVICES_MOUNTED; then
+        echo "Unmounting filesystems in $BUILDDIR"
+        for dir in dev/pts dev sys proc; do
+            umount "$BUILDDIR/$dir"
+        done
+        DEVICES_MOUNTED=false
+    fi
+}
+
+# Exit handler
+TMP_BUILDDIR=
+cleanup()
+{
+    cleanup_mounts || true
+    if [ -n "$TMP_BUILDDIR" ]; then
+        rm -rf "$TMP_BUILDDIR"
+    fi
+}
+trap cleanup EXIT
+
+if [ -n "$BUILDDIR" ]; then
+    # Create specified build directory
+    echo "Creating $BUILDDIR"
+    mkdir -p "$BUILDDIR"
+else
+    # Create a temporary build directory in /var/tmp since it could be
+    # fairly large
+    TMP_BUILDDIR=$(mktemp -d -p /var/tmp deb-ostree-builder-XXXXXXXX)
+    BUILDDIR=$TMP_BUILDDIR
+    echo "Using temporary directory $BUILDDIR for build"
+fi
+
+# Ensure that dracut makes generic initramfs instead of looking just
+# at the host configuration. This is also in the dracut-config-generic
+# package, but that only gets installed after dracut makes the first
+# initramfs.
+echo "Configuring dracut for generic initramfs"
+mkdir -p "$BUILDDIR"/etc/dracut.conf.d
+cat > "$BUILDDIR"/etc/dracut.conf.d/90-deb-ostree.conf <<EOF
+# Don't make host-specific initramfs
+hostonly=no
+EOF
+
+# Define a temporary policy-rc.d that ensures that no daemons are
+# launched from the installation.
+mkdir -p "$BUILDDIR"/usr/sbin
+cat > "$BUILDDIR"/usr/sbin/policy-rc.d <<EOF
+#!/bin/sh
+exit 101
+EOF
+chmod +x "$BUILDDIR"/usr/sbin/policy-rc.d
+
+# Mount common kernel filesystems. dracut expects /dev to be mounted.
+echo "Mounting filesystems in $BUILDDIR"
+DEVICES_MOUNTED=true
+for dir in proc sys dev dev/pts; do
+    mkdir -p "$BUILDDIR/$dir"
+    mount --bind "/$dir" "$BUILDDIR/$dir"
+done
+
+# Build with multistrap
+echo "Building system with multistrap in $BUILDDIR"
+multistrap -f "$CONFIG" -d "$BUILDDIR"
+
+# All done with filesystems
+cleanup_mounts
+
+# Remove temporary policy-rc.d
+rm -f "$BUILDDIR"/usr/sbin/policy-rc.d
+
+# Cleanup cruft
+echo "Preparing system for OSTree"
+rm -rf \
+   "$BUILDDIR"/boot/*.bak \
+   "$BUILDDIR"/etc/apt/sources.list~ \
+   "$BUILDDIR"/etc/apt/trusted.gpg~ \
+   "$BUILDDIR"/etc/{passwd,group,shadow,gshadow}- \
+   "$BUILDDIR"/var/cache/debconf/*-old \
+   "$BUILDDIR"/var/lib/dpkg/*-old \
+   "$BUILDDIR"/boot/{initrd.img,vmlinuz} \
+   "$BUILDDIR"/{initrd.img,vmlinuz}{,.old}
+
+# Remove dbus machine ID cache (makes each system unique)
+rm -f "$BUILDDIR"/var/lib/dbus/machine-id "$BUILDDIR"/etc/machine-id
+
+# Remove resolv.conf copied from the host by debootstrap. The settings
+# are only valid on the target host and will be populated at runtime.
+rm -f "$BUILDDIR"/etc/resolv.conf
+
+# Remove temporary files
+rm -rf "$BUILDDIR"/var/cache/man/*
+rm -rf "$BUILDDIR"/tmp "$BUILDDIR"/var/tmp
+mkdir -p "$BUILDDIR"/tmp "$BUILDDIR"/var/tmp
+chmod 1777 "$BUILDDIR"/tmp "$BUILDDIR"/var/tmp
+
+# OSTree uses a single checksum of the combined kernel and initramfs
+# to manage boot. Determine the checksum and rename the files the way
+# OSTree expects.
+echo "Renaming kernel and initramfs per OSTree requirements"
+pushd "$BUILDDIR"/boot >/dev/null
+
+vmlinuz_match=(vmlinuz*)
+vmlinuz_file=${vmlinuz_match[0]}
+initrd_match=(initrd.img* initramfs*)
+initrd_file=${initrd_match[0]}
+
+csum=$(cat ${vmlinuz_file} ${initrd_file} | \
+             sha256sum --binary | \
+             awk '{print $1}')
+echo "OSTree boot checksum: ${csum}"
+
+mv ${vmlinuz_file} ${vmlinuz_file}-${csum}
+mv ${initrd_file} ${initrd_file/initrd.img/initramfs}-${csum}
+
+popd >/dev/null
+
+# OSTree only commits files or symlinks
+rm -rf "$BUILDDIR"/dev
+mkdir -p "$BUILDDIR"/dev
+
+# Fixup home directory base paths for OSTree
+sed -i -e 's|DHOME=/home|DHOME=/sysroot/home|g' \
+    "${BUILDDIR}"/etc/adduser.conf
+sed -i -e 's|# HOME=/home|HOME=/sysroot/home|g' \
+    "${BUILDDIR}"/etc/default/useradd
+
+# Move /etc to /usr/etc.
+#
+# FIXME: Need to handle passwd and group to be updatable. This can be
+# done with libnss-altfiles, though that has other drawbacks.
+if [ -d "${BUILDDIR}"/usr/etc ]; then
+    echo "ERROR: Non-empty /usr/etc found!" >&2
+    ls -lR "${BUILDDIR}"/usr/etc
+    exit 1
+fi
+mv "${BUILDDIR}"/etc "${BUILDDIR}"/usr
+
+# Move dpkg database to /usr so it's accessible after the OS /var is
+# mounted, but make a symlink so it works without modifications to dpkg
+# or apt
+mkdir -p "${BUILDDIR}"/usr/share/dpkg
+if [ -e "${BUILDDIR}"/usr/share/dpkg/database ]; then
+    echo "ERROR: /usr/share/dpkg/database already exists!" >&2
+    ls -lR "${BUILDDIR}"/usr/share/dpkg/database >&2
+    exit 1
+fi
+mv "${BUILDDIR}"/var/lib/dpkg "${BUILDDIR}"/usr/share/dpkg/database
+ln -sr "${BUILDDIR}"/usr/share/dpkg/database \
+   "${BUILDDIR}"/var/lib/dpkg
+
+# tmpfiles.d setup to make the ostree root compatible with persistent
+# directories in the sysroot.
+cat > "${BUILDDIR}"/usr/lib/tmpfiles.d/ostree.conf <<EOF
+d /sysroot/home 0755 root root -
+d /sysroot/root 0700 root root -
+d /var/opt 0755 root root -
+d /var/local 0755 root root -
+d /run/media 0755 root root -
+L /var/lib/dpkg - - - - ../../usr/share/dpkg/database
+EOF
+
+# Create symlinks in the ostree for persistent directories.
+mkdir -p "${BUILDDIR}"/sysroot
+rm -rf "${BUILDDIR}"/{home,root,media,opt} "${BUILDDIR}"/usr/local
+ln -s /sysroot/ostree "${BUILDDIR}"/ostree
+ln -s /sysroot/home "${BUILDDIR}"/home
+ln -s /sysroot/root "${BUILDDIR}"/root
+ln -s /var/opt "${BUILDDIR}"/opt
+ln -s /var/local "${BUILDDIR}"/usr/local
+ln -s /run/media "${BUILDDIR}"/media
+
+# Now ready to commit. Make the repo if necessary. An archive-z2 repo
+# is used since the intention is to use this repo to serve updates
+# from.
+mkdir -p "$REPO"
+if [ ! -f "$REPO"/config ]; then
+    echo "Initialiazing OSTree repo $REPO"
+    ostree --repo="$REPO" init --mode=archive-z2
+fi
+
+# Make the commit. The ostree ref is flatpak style.
+branch="os/debian/$ARCH/$SUITE"
+COMMIT_OPTS=(
+    --repo="$REPO"
+    --branch="$branch"
+    --subject="Build $SUITE $ARCH $(date --iso-8601=seconds)"
+    --skip-if-unchanged
+    --table-output
+)
+for id in ${GPG_SIGN[@]}; do
+    COMMIT_OPTS+=(--gpg-sign="$id")
+done
+if [ -n "$GPG_HOMEDIR" ]; then
+    COMMIT_OPTS+=(--gpg-homedir="$GPG_HOMEDIR")
+fi
+echo "Committing $BUILDDIR to $REPO branch $branch"
+ostree commit "${COMMIT_OPTS[@]}" "$BUILDDIR"
+
+# Update the repo summary
+SUMMARY_OPTS=(
+    --repo="$REPO"
+    --update
+)
+for id in ${GPG_SIGN[@]}; do
+    SUMMARY_OPTS+=(--gpg-sign="$id")
+done
+if [ -n "$GPG_HOMEDIR" ]; then
+    SUMMARY_OPTS+=(--gpg-homedir="$GPG_HOMEDIR")
+fi
+echo "Updating $REPO summary file"
+ostree summary "${SUMMARY_OPTS[@]}"
diff --git a/debian/ostree-boot-examples/modified-deb-ostree-builder b/debian/ostree-boot-examples/modified-deb-ostree-builder
new file mode 100644 (file)
index 0000000..88042e9
--- /dev/null
@@ -0,0 +1,321 @@
+#!/bin/bash -e
+
+# deb-ostree-builder - Build bootable Debian OSTree commits
+# This version has been modified to install extra packages from
+# /root/extra-packages.
+#
+# Copyright (C) 2017  Dan Nicholson <nicholson@endlessm.com>
+# Copyright (C) 2019  Simon McVittie
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+PROG=$(readlink -f "$0")
+PROGDIR=$(dirname "$PROG")
+
+# Defaults
+ARCH=$(dpkg --print-architecture)
+BUILDDIR=
+GPG_SIGN=()
+GPG_HOMEDIR=
+
+usage() {
+    cat <<EOF
+Usage: $0 [OPTION...] CONFIG SUITE REPO
+
+  -a, --arch           build architecture
+  -d, --dir            build directory
+  --gpg-sign           GPG key ID to use for signing
+  --gpg-homedir                GPG homedir to find keys
+  -h, --help           show this message and exit
+
+deb-ostree-builder constructs a Debian OS for use as a bootable
+OSTree. It uses debootstrap to construct the OS, adjusts it to be
+compatible with OSTree, and then commits it to a repository.
+
+CONFIG is a multistrap configuration file. SUITE is the distribution
+codename. This is used for the OSTree ref and must match the
+multistrap configuration. REPO is the path the the OSTree repository
+where the commit will be made.
+EOF
+}
+
+ARGS=$(getopt -n "$0" \
+             -o a:d:h \
+             -l arch:,dir:,gpg-sign:,gpg-homedir:,help \
+             -- "$@")
+eval set -- "$ARGS"
+
+while true; do
+    case "$1" in
+       -a|--arch)
+           ARCH=$2
+           shift 2
+           ;;
+        -d|--dir)
+            BUILDDIR=$2
+            shift 2
+            ;;
+       --gpg-sign)
+           GPG_SIGN+=($2)
+           shift 2
+           ;;
+       --gpg-homedir)
+           GPG_HOMEDIR=$2
+           shift 2
+           ;;
+       -h|--help)
+           usage
+           exit 0
+           ;;
+       --)
+           shift
+           break
+           ;;
+    esac
+done
+
+if [ $# -lt 3 ]; then
+    echo "Must specify CONFIG, SUITE and REPO" >&2
+    exit 1
+fi
+
+CONFIG=$1
+SUITE=$2
+REPO=$3
+
+# Mount cleanup handler
+DEVICES_MOUNTED=false
+cleanup_mounts()
+{
+    if $DEVICES_MOUNTED; then
+        echo "Unmounting filesystems in $BUILDDIR"
+        for dir in dev/pts dev sys proc; do
+            umount "$BUILDDIR/$dir"
+        done
+        DEVICES_MOUNTED=false
+    fi
+}
+
+# Exit handler
+TMP_BUILDDIR=
+cleanup()
+{
+    cleanup_mounts || true
+    if [ -n "$TMP_BUILDDIR" ]; then
+        rm -rf "$TMP_BUILDDIR"
+    fi
+}
+trap cleanup EXIT
+
+if [ -n "$BUILDDIR" ]; then
+    # Create specified build directory
+    echo "Creating $BUILDDIR"
+    mkdir -p "$BUILDDIR"
+else
+    # Create a temporary build directory in /var/tmp since it could be
+    # fairly large
+    TMP_BUILDDIR=$(mktemp -d -p /var/tmp deb-ostree-builder-XXXXXXXX)
+    BUILDDIR=$TMP_BUILDDIR
+    echo "Using temporary directory $BUILDDIR for build"
+fi
+
+# Ensure that dracut makes generic initramfs instead of looking just
+# at the host configuration. This is also in the dracut-config-generic
+# package, but that only gets installed after dracut makes the first
+# initramfs.
+echo "Configuring dracut for generic initramfs"
+mkdir -p "$BUILDDIR"/etc/dracut.conf.d
+cat > "$BUILDDIR"/etc/dracut.conf.d/90-deb-ostree.conf <<EOF
+# Don't make host-specific initramfs
+hostonly=no
+EOF
+
+# Define a temporary policy-rc.d that ensures that no daemons are
+# launched from the installation.
+mkdir -p "$BUILDDIR"/usr/sbin
+cat > "$BUILDDIR"/usr/sbin/policy-rc.d <<EOF
+#!/bin/sh
+exit 101
+EOF
+chmod +x "$BUILDDIR"/usr/sbin/policy-rc.d
+
+# Mount common kernel filesystems. dracut expects /dev to be mounted.
+echo "Mounting filesystems in $BUILDDIR"
+DEVICES_MOUNTED=true
+for dir in proc sys dev dev/pts; do
+    mkdir -p "$BUILDDIR/$dir"
+    mount --bind "/$dir" "$BUILDDIR/$dir"
+done
+
+# Build with multistrap
+echo "Building system with multistrap in $BUILDDIR"
+multistrap -f "$CONFIG" -d "$BUILDDIR"
+
+# This is a hack for testing ostree-boot before it is in the Debian archive
+if [ -d /root/extra-packages ]; then
+    mkdir "$BUILDDIR/root/extra-packages"
+    cp /root/extra-packages/*.deb "$BUILDDIR/root/extra-packages"
+    chroot "$BUILDDIR" apt -y update
+    chroot "$BUILDDIR" apt -y install /root/extra-packages/*.deb
+    rm -fr "$BUILDDIR/root/extra-packages"
+fi
+
+# All done with filesystems
+cleanup_mounts
+
+# Remove temporary policy-rc.d
+rm -f "$BUILDDIR"/usr/sbin/policy-rc.d
+
+# Cleanup cruft
+echo "Preparing system for OSTree"
+rm -rf \
+   "$BUILDDIR"/boot/*.bak \
+   "$BUILDDIR"/etc/apt/sources.list~ \
+   "$BUILDDIR"/etc/apt/trusted.gpg~ \
+   "$BUILDDIR"/etc/{passwd,group,shadow,gshadow}- \
+   "$BUILDDIR"/var/cache/debconf/*-old \
+   "$BUILDDIR"/var/lib/dpkg/*-old \
+   "$BUILDDIR"/boot/{initrd.img,vmlinuz} \
+   "$BUILDDIR"/{initrd.img,vmlinuz}{,.old}
+
+# Remove dbus machine ID cache (makes each system unique)
+rm -f "$BUILDDIR"/var/lib/dbus/machine-id "$BUILDDIR"/etc/machine-id
+
+# Remove resolv.conf copied from the host by debootstrap. The settings
+# are only valid on the target host and will be populated at runtime.
+rm -f "$BUILDDIR"/etc/resolv.conf
+
+# Remove temporary files
+rm -rf "$BUILDDIR"/var/cache/man/*
+rm -rf "$BUILDDIR"/tmp "$BUILDDIR"/var/tmp
+mkdir -p "$BUILDDIR"/tmp "$BUILDDIR"/var/tmp
+chmod 1777 "$BUILDDIR"/tmp "$BUILDDIR"/var/tmp
+
+# OSTree uses a single checksum of the combined kernel and initramfs
+# to manage boot. Determine the checksum and rename the files the way
+# OSTree expects.
+echo "Renaming kernel and initramfs per OSTree requirements"
+pushd "$BUILDDIR"/boot >/dev/null
+
+vmlinuz_match=(vmlinuz*)
+vmlinuz_file=${vmlinuz_match[0]}
+initrd_match=(initrd.img* initramfs*)
+initrd_file=${initrd_match[0]}
+
+csum=$(cat ${vmlinuz_file} ${initrd_file} | \
+             sha256sum --binary | \
+             awk '{print $1}')
+echo "OSTree boot checksum: ${csum}"
+
+mv ${vmlinuz_file} ${vmlinuz_file}-${csum}
+mv ${initrd_file} ${initrd_file/initrd.img/initramfs}-${csum}
+
+popd >/dev/null
+
+# OSTree only commits files or symlinks
+rm -rf "$BUILDDIR"/dev
+mkdir -p "$BUILDDIR"/dev
+
+# Fixup home directory base paths for OSTree
+sed -i -e 's|DHOME=/home|DHOME=/sysroot/home|g' \
+    "${BUILDDIR}"/etc/adduser.conf
+sed -i -e 's|# HOME=/home|HOME=/sysroot/home|g' \
+    "${BUILDDIR}"/etc/default/useradd
+
+# Move /etc to /usr/etc.
+#
+# FIXME: Need to handle passwd and group to be updatable. This can be
+# done with libnss-altfiles, though that has other drawbacks.
+if [ -d "${BUILDDIR}"/usr/etc ]; then
+    echo "ERROR: Non-empty /usr/etc found!" >&2
+    ls -lR "${BUILDDIR}"/usr/etc
+    exit 1
+fi
+mv "${BUILDDIR}"/etc "${BUILDDIR}"/usr
+
+# Move dpkg database to /usr so it's accessible after the OS /var is
+# mounted, but make a symlink so it works without modifications to dpkg
+# or apt
+mkdir -p "${BUILDDIR}"/usr/share/dpkg
+if [ -e "${BUILDDIR}"/usr/share/dpkg/database ]; then
+    echo "ERROR: /usr/share/dpkg/database already exists!" >&2
+    ls -lR "${BUILDDIR}"/usr/share/dpkg/database >&2
+    exit 1
+fi
+mv "${BUILDDIR}"/var/lib/dpkg "${BUILDDIR}"/usr/share/dpkg/database
+ln -sr "${BUILDDIR}"/usr/share/dpkg/database \
+   "${BUILDDIR}"/var/lib/dpkg
+
+# tmpfiles.d setup to make the ostree root compatible with persistent
+# directories in the sysroot.
+cat > "${BUILDDIR}"/usr/lib/tmpfiles.d/ostree.conf <<EOF
+d /sysroot/home 0755 root root -
+d /sysroot/root 0700 root root -
+d /var/opt 0755 root root -
+d /var/local 0755 root root -
+d /run/media 0755 root root -
+L /var/lib/dpkg - - - - ../../usr/share/dpkg/database
+EOF
+
+# Create symlinks in the ostree for persistent directories.
+mkdir -p "${BUILDDIR}"/sysroot
+rm -rf "${BUILDDIR}"/{home,root,media,opt} "${BUILDDIR}"/usr/local
+ln -s /sysroot/ostree "${BUILDDIR}"/ostree
+ln -s /sysroot/home "${BUILDDIR}"/home
+ln -s /sysroot/root "${BUILDDIR}"/root
+ln -s /var/opt "${BUILDDIR}"/opt
+ln -s /var/local "${BUILDDIR}"/usr/local
+ln -s /run/media "${BUILDDIR}"/media
+
+# Now ready to commit. Make the repo if necessary. An archive-z2 repo
+# is used since the intention is to use this repo to serve updates
+# from.
+mkdir -p "$REPO"
+if [ ! -f "$REPO"/config ]; then
+    echo "Initialiazing OSTree repo $REPO"
+    ostree --repo="$REPO" init --mode=archive-z2
+fi
+
+# Make the commit. The ostree ref is flatpak style.
+branch="os/debian/$ARCH/$SUITE"
+COMMIT_OPTS=(
+    --repo="$REPO"
+    --branch="$branch"
+    --subject="Build $SUITE $ARCH $(date --iso-8601=seconds)"
+    --skip-if-unchanged
+    --table-output
+)
+for id in ${GPG_SIGN[@]}; do
+    COMMIT_OPTS+=(--gpg-sign="$id")
+done
+if [ -n "$GPG_HOMEDIR" ]; then
+    COMMIT_OPTS+=(--gpg-homedir="$GPG_HOMEDIR")
+fi
+echo "Committing $BUILDDIR to $REPO branch $branch"
+ostree commit "${COMMIT_OPTS[@]}" "$BUILDDIR"
+
+# Update the repo summary
+SUMMARY_OPTS=(
+    --repo="$REPO"
+    --update
+)
+for id in ${GPG_SIGN[@]}; do
+    SUMMARY_OPTS+=(--gpg-sign="$id")
+done
+if [ -n "$GPG_HOMEDIR" ]; then
+    SUMMARY_OPTS+=(--gpg-homedir="$GPG_HOMEDIR")
+fi
+echo "Updating $REPO summary file"
+ostree summary "${SUMMARY_OPTS[@]}"
diff --git a/debian/ostree-boot-examples/ostree-1.conf b/debian/ostree-boot-examples/ostree-1.conf
new file mode 100644 (file)
index 0000000..aec2ea7
--- /dev/null
@@ -0,0 +1,17 @@
+[general]
+arch=amd64
+noauth=false
+aptsources=debian
+bootstrap=debian
+addimportant=true
+cleanup=true
+
+[debian]
+packages=linux-image-amd64 grub-pc dracut ostree-boot
+# to boot root partitions on LVM
+packages=lvm2
+# usrmerge is required by the builder script
+packages=usrmerge
+source=http://deb.debian.org/debian
+keyring=debian-archive-keyring
+suite=sid
diff --git a/debian/ostree-boot-examples/ostree-2.conf b/debian/ostree-boot-examples/ostree-2.conf
new file mode 100644 (file)
index 0000000..d606e47
--- /dev/null
@@ -0,0 +1,19 @@
+[general]
+arch=amd64
+noauth=false
+aptsources=debian
+bootstrap=debian
+addimportant=true
+cleanup=true
+
+[debian]
+packages=linux-image-amd64 grub-pc dracut ostree-boot
+# to boot root partitions on LVM
+packages=lvm2
+# usrmerge is required by the builder script
+packages=usrmerge
+# an extra package to verify deployment change
+packages=hello
+source=http://deb.debian.org/debian
+keyring=debian-archive-keyring
+suite=sid